<?php
namespace phiction;

abstract class terminal
{
    const N = "\033[0m";
    const H = "\033[1m";
    const R = "\033[31m";
    const G = "\033[32m";
    const B = "\033[34m";
    const RG = "\033[33m";
    const RB = "\033[35m";
    const GB = "\033[36m";
    const RGB = "\033[37m";
    const IR = "\033[41m";
    const IG = "\033[42m";
    const IB = "\033[44m";
    const IRG = "\033[43m";
    const IRB = "\033[45m";
    const IGB = "\033[46m";
    const IRGB = "\033[47m";

    abstract function kv(string $key, string $value, string $kcolor, string $vcolor): string;
    abstract function color(string $color, string $text): string;
    abstract function width(): int;

    static function create(config $config)
    {
        return $config->colorful
            ? new terminal_colorful($config)
            : new terminal_colorless($config);
    }
}

class terminal_colorful extends terminal
{
    private $width = 80;

    function __construct(config $config)
    {
        if ($config->posix_compliant)
            $this->width = (int)exec('tput cols');
    }

    function kv(string $key, string $value, string $kcolor=self::B, string $vcolor=self::H.self::RB): string
    {
        return $kcolor . $key . $vcolor . $value . self::N;
    }

    function color(string $color, string $text): string
    {
        return $color . $text . self::N;
    }

    function width(): int
    {
        return $this->width;
    }
}

class terminal_colorless extends terminal
{
    private $width = 80;

    function __construct(config $config)
    {
        if ($config->posix_compliant)
            $this->width = (int)exec('tput cols');
    }

    function kv(string $key, string $value, string $kcolor=self::N, string $vcolor=self::N): string
    {
        return $key . $value;
    }

    function color(string $color, string $text): string
    {
        return $text;
    }

    function width(): int
    {
        return $this->width;
    }
}

